<template>
  <div>
    <div v-if="isModel">
      <el-dialog :fullscreen="fullscreen" :close-on-click-modal="false" :visible.sync="dialogFormVisible" append-to-body
        :width="width + 'px'" :show-close="false" :close-on-press-escape="false" v-bind="$attrs" v-dragH v-dragW
        v-dragM>
        <template #title>
          <slot name="add-title">
            <div class="dialog-title">
              <div class="dialog-title-left" v-html="get_title"></div>
              <div class="dialog-title-right">
                <el-button type="text" class="m-close" :icon="globlSetting.close.icon" :style="globlSetting.close.style"
                  @click="onClose()"></el-button>
              </div>
            </div>
          </slot>
        </template>
        <el-form ref="ruleForm" :model="form" inline :style="`padding: 10px; ${!border ? '' : 'border: 1px solid #dcdfe6; border-radius: 10px'
          } `" :disabled="showCommitBtn == false" :status-icon="true" :show-message="doShowErrMessage()"
          :validate-on-rule-change="false">
          <div style="display: inline-flex" v-for="(item, index) in get_form_attrs()" :key="index">
            <div v-if="item['bj'] === true">
              <slot :name="item['key']" :info="form"><b style="color: red">在这里可以标记！</b></slot>
            </div>
            <div v-else :style="doShowErrMessage() ? 'padding-bottom: 12px' : ''">
              <sub-form :item="item" :subform="form" :labelWidth="labelWidth" :itemWidth="itemWidth"
                :showCommitBtn="showCommitBtn" :justify="justify" :formAttrs="formAttrs">
                <template v-for="(_, name) in $scopedSlots" v-slot:[name]="data">
                  <slot :name="name" v-bind="data"></slot>
                </template>
              </sub-form>
            </div>
          </div>
        </el-form>
        <template #footer class="dialog-footer" :style="`text-align:${center(this)}`" v-if="showFooter">
          <slot name="spareLBtn" :info="form"></slot>
          <slot name="add-footer">
            <el-button v-bind="btnAttrs('commit')" v-show="isreadonly == false" @click="saveData"
              v-if="showCommitBtn">{{
                doCommitText() }}</el-button>
            <el-button v-bind="btnAttrs('cancel')" @click="onClose()" v-if="showCancelBtn">{{ doCancelText() }}
            </el-button>
          </slot>
          <slot name="spareRBtn"></slot>
        </template>
      </el-dialog>
    </div>
    <div v-else>
      <el-form ref="ruleForm" :model="form" inline :style="`padding: 10px; ${!border ? '' : 'border: 1px solid #dcdfe6; border-radius: 10px'
        } `" :disabled="showCommitBtn == false" :status-icon="true" :show-message="doShowErrMessage()">
        <div v-for="(item, index) in get_form_attrs()" :key="index" style="display: inline-flex">
          <div v-if="item['bj'] === true">
            <slot :name="item['key']" :info="form"><b style="color: red">在这里可以标记！</b></slot>
          </div>
          <div v-else :style="doShowErrMessage() ? 'padding-bottom: 12px' : ''">
            <sub-form :item="item" :subform="form" :labelWidth="labelWidth" :itemWidth="itemWidth"
              :showCommitBtn="showCommitBtn" :justify="justify" :formAttrs="formAttrs">
              <template v-for="(_, name) in $scopedSlots" v-slot:[name]="data">
                <slot :name="name" v-bind="data"></slot>
              </template>
            </sub-form>
          </div>
        </div>
      </el-form>
      <div :style="`text-align:${center(this)}`" v-if="showFooter">
        <slot name="spareLBtn" :info="form"></slot>
        <slot name="add-footer">
          <el-button v-bind="btnAttrs('commit')" v-show="isreadonly == false" @click="saveData" v-if="showCommitBtn">{{
            doCommitText() }}</el-button>
          <el-button v-bind="btnAttrs('cancel')" @click="onClose()" v-if="showCancelBtn">{{ doCancelText() }}
          </el-button>
        </slot>
        <slot name="spareRBtn"></slot>
      </div>
    </div>
  </div>
</template>

<script>
import dragM from "../directive/dialog/drag.js";
import dragW from "../directive/dialog/dragWidth.js";
import dragH from "../directive/dialog/dragHeight.js";
import opt from "./optimize.js";
import dayjs from "dayjs";
import subForm from "./sub-form.vue";
import bus from "./bus.js";
export default {
  components: { subForm },
  name: "g-add-form",
  props: {
    //是否模态
    isModel: { type: Boolean, default: true },
    //全屏
    fullscreen: { type: Boolean, default: false },
    //弹窗标题
    title: { type: String, default: "" },
    //表单属性
    formAttrs: { type: Object, default: () => { } },
    //编辑实体
    formInfo: { type: Object, default: () => { } },
    //弹窗宽度
    width: { type: Number, default: 720 },
    //是否禁用FORM表单
    isreadonly: { type: Boolean, default: false },
    //弹窗footer显示位置 left|center|right
    center: {
      type: Function,
      default: (a) => {
        if (a.globlSetting.formFooterAlign) {
          return a.globlSetting.formFooterAlign(a);
        } else {
          return "right";
        }
      },
    },
    //提交按钮文本
    commitText: {
      type: Function,
      default: (a) => {
        if (a?.globlSetting?.commit?.text) {
          return a?.globlSetting?.commit?.text;
        } else {
          return "提交";
        }
      },
    },
    //取消按钮文本
    cancelText: {
      type: Function,
      default: (a) => {
        if (a?.globlSetting?.cancel?.text) {
          return a?.globlSetting?.cancel?.text;
        } else {
          return "取消";
        }
      },
    },
    //操作按钮样式
    btnTypes: {
      type: Object,
      default: (a) => { },
    },
    //是否显示提交按钮
    showCommitBtn: { type: Boolean, default: true },
    //是否显示取消按钮
    showCancelBtn: { type: Boolean, default: true },
    //是否显示footer
    showFooter: { type: Boolean, default: true },
    //表单项目宽度
    itemWidth: { type: Number, default: 308 },
    //表单项标题宽度
    labelWidth: { type: Number, default: 120 },
    //表单表格是否显示边框
    border: { type: Boolean, default: false },
    //是否显示错误信息
    showErrMessage: {
      type: Function,
      default: (a) => {
        if (a?.globlSetting?.showErrMessage) {
          return a?.globlSetting?.showErrMessage();
        } else {
          return true;
        }
      },
    },
    //表单label是否分散对齐
    justify: {
      type: Function,
      default: (a) => {
        if (a?.globlSetting?.formLabelJustify) {
          return a?.globlSetting?.formLabelJustify();
        } else {
          return false;
        }
      },
    },
  },
  directives: {
    //dialogDrag: vDrag,
    dragW: dragW,
    dragH: dragH,
    dragM: dragM,
  },
  data() {
    return {
      dialogFormVisible: true,
      form: {},
      plain: false,
      btnAttrs: (key) => {
        return {
          icon: this.globlSetting[key].icon,
          type: this.globlSetting[key].type,
          plain: this.globlSetting[key].plain,
          round: this.globlSetting[key].round,
          size: this.globlSetting[key].size,
          circle: this.globlSetting[key].circle,
          style: this.globlSetting[key].style,
        };
      },
    };
  },
  methods: {
    async onClose() {
      opt.debounce(() => {
        this.$emit("close", this);
      }, 200);
    },
    saveData() {
      opt.debounce(() => {
        this.$refs["ruleForm"].validate(async (valid) => {
          if (valid) {
            let arr = this.get_form_attrs().filter((a) => a.bj === true);
            if (arr?.length > 0) {
              arr?.forEach((element) => {
                Reflect.deleteProperty(this.form, element.key);
              });
            }
            let dt = this.get_form_attrs().filter(
              (a) => a.date == true || a.time == true
            );
            dt.forEach((a) => {
              if (dayjs(this.form[a.key]).isValid()) {
                this.form[a.key] = dayjs(this.form[a.key]).format(
                  a.time == true
                    ? "YYYY-MM-DD HH:mm:ss"
                    : a.date == true
                      ? "YYYY-MM-DD"
                      : "YYYY-MM-DD"
                );
              }
            });
            let defaultResult = { isadd: false, savedData: {}, closeForm: true, resetForm: false, bus: true };
            let result = await new Promise((resolve) => {
              this.$emit('saveData', this.form, (cbResult) => {
                resolve(Object.assign(defaultResult, cbResult));
              }, this);
            })
            if (result.closeForm) {
              this.$destroy();
            } else {
              if (result.resetForm == true) {
                this.$refs.ruleForm.resetFields();
                this.form = Object.fromEntries(this.get_form_attrs().map((a) => [a.key, a.val]));
              }
            }
            if (bus) {
              console.log("全局事件定制了", this.form)
              bus.$emit("form-save", result.isadd ? Object.assign(this.form, result.savedData) : this.form, result.isadd);//注册全局事件
            }
          } else {
            console.log("validate error");
          }
        });
      }, 500)
    },
    get_form_attrs() {
      let t = Object.entries(this.formAttrs).map((a) => {
        if (!a[1].num) {
          a[1].num = 0;
        } else {
          a[1].num = parseFloat(a[1].num);
        }
        let obj = a[1];
        obj.key = a[0];
        return obj;
      });
      t.sort((a, b) => a.num - b.num);
      return t;
    },

    doShowErrMessage() {
      return this.showErrMessage(this);
    },
    doCommitText() {
      return this.commitText(this);
    },
    doCancelText() {
      return this.cancelText(this);
    },
  },
  computed: {
    get_title() {
      if (!this.title) {
        if (this.formInfo) {
          if (this.showCommitBtn == false) {
            return "查看";
          } else {
            return "编辑";
          }
        } else {
          return "新增";
        }
      } else {
        return this.title;
      }
    },
  },
  mounted() {
    let initModel = Object.fromEntries(
      this.get_form_attrs().map((a) => [a.key, a.val])
    );
    if (!this.formInfo) {
      this.form = initModel;
    } else {
      this.form = Object.assign(initModel, this.formInfo);
    }
    let t = this.get_form_attrs().filter((a) => a.query);
    if (t && t.length > 0) {
      t.forEach((element) => {
        let tempwords = this.form[element["words"]];
        this.$set(element, "dicts", [
          { label: tempwords, value: this.form[element["key"]] },
        ]);
      });
    }
    if (this.btnTypes) {
      for (const i of Object.keys(this.btnTypes)) {
        this.globlSetting[i].type = this.btnTypes[i]?.type;
      }
    }
    document.onkeydown = function (evt) {
      //document.all可以判断浏览器是否是IE，是页面内所有元素的一个集合
      var isie = document.all ? true : false;
      var key;
      var srcobj;
      // if the agent is an IE browser, it's easy to do this.
      if (isie) {
        key = event.keyCode;
        srcobj = event.srcElement; //event.srcElement，触发这个事件的源对象
      } else {
        key = evt.which;
        srcobj = evt.target; //target是Firefox下的属性
      }
      if (
        key == 13 &&
        srcobj.type != "button" &&
        srcobj.type != "submit" &&
        srcobj.type != "reset" &&
        srcobj.type != "textarea" &&
        srcobj.type != ""
      ) {
        if (isie) event.keyCode = 9;
        //设置按键为tab键
        else {
          var el = getNextElement(evt.target);
          if (el) {
            if (
              el.type != "hidden" //nothing to do here.
            );
            else while (el.type == "hidden") el = getNextElement(el);
            if (!el) return false;
            else el.focus();
          }
        }
      }
    };
    function getNextElement(field) {
      var form = field.form;
      if (form && form.elements && form.elements.length) {
        for (var e = 0; e < form.elements.length; e++) {
          if (field == form.elements[e]) break;
        }
        return form.elements[++e % form.elements.length];
      }
    }
    if (this.globlSetting?.plain) {
      this.plain = this.globlSetting?.plain;
    }
  },

  beforeDestroy() {
    this.onClose();
  }
};
</script>

<style>
.el-dialog {
  display: flex;
  display: -ms-flex;
  /* 兼容IE */
  flex-direction: column;
  -ms-flex-direction: column;
  /* 兼容IE */
  margin: 0 !important;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  max-height: calc(100% - 2px);
  max-width: calc(100% - 2px);
}

.el-dialog .el-dialog__body {
  max-height: 100%;
  flex: 1;
  -ms-flex: 1 1 auto;
  /* 兼容IE */
  overflow-y: auto;
  overflow-x: hidden;
}

.el-dialog__header {
  padding-top: 5px !important;
  background-color: #f5f5f5;
}

.el-dialog__body {
  border-top: 1px solid #dcdfe6;
  border-bottom: 1px solid #dcdfe6;
}

.el-dialog__footer {
  background-color: #f5f5f5;
  padding: 15px !important;
}

.el-input__inner {
  padding-right: 0px !important;
}
</style>

<style scoped>
.dialog-title {
  display: flex;
  width: 100%;
  align-items: center;
}

.dialog-title-left {
  display: flex;
  flex: 1;
  justify-content: flex-start;
}

.dialog-title-right {
  display: flex;
  width: 50px;
  justify-content: flex-end;
}

.m-close:hover {
  transform: scale(1.3);
}
</style>
